﻿#include "includes.h"

#define MAX_COIL_NUM            100
#define MAX_INPUT_STATUS_NUM    100
#define MAX_HOLD_REG_NUM        100
#define MAX_INPUT_REG_NUM       100

#define USE_BIT_STORAGE         1

typedef struct {
    uint16_t start_addr;
    uint16_t num;
    uint8_t *data;
    uint8_t *data_w;
}vdata_modbus_coil_t;

typedef struct {
    uint16_t start_addr;
    uint16_t num;
    uint8_t *data;
}vdata_modbus_input_status_t;

typedef struct {
    uint16_t start_addr;
    uint16_t num;
    uint16_t *data;
    uint16_t *data_w;
}vdata_modbus_hold_reg_t;

typedef struct {
    uint16_t start_addr;
    uint16_t num;
    uint16_t *data;
}vdata_modbus_input_reg_t;

typedef struct {
    union{
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
        };
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t start_addr;
            uint16_t coil_num;
            uint16_t crc16;
        }func_01_recv;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t start_addr;
            uint16_t input_status_num;
            uint16_t crc16;
        }func_02_recv;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t start_addr;
            uint16_t hold_reg_num;
            uint16_t crc16;
        }func_03_recv;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t start_addr;
            uint16_t input_reg_num;
            uint16_t crc16;
        }func_04_recv;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t start_addr;
            uint16_t coil_value;
            uint16_t crc16;
        }func_05_recv;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t start_addr;
            uint16_t hold_reg_value;
            uint16_t crc16;
        }func_06_recv;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t start_addr;
            uint16_t coil_num;
            uint8_t  bytes;
            uint8_t  *data;
            uint16_t crc16;
        }func_15_recv;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t start_addr;
            uint16_t hold_reg_num;
            uint8_t  bytes;
            uint16_t  *data;
            uint16_t crc16;
        }func_16_recv;
    };
    union{
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint8_t  bytes;
            uint8_t  *coil_data;
            uint16_t crc16;
        }func_01_send;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint8_t  bytes;
            uint8_t  *input_status_data;
            uint16_t crc16;
        }func_02_send;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint8_t  bytes;
            uint16_t  *hold_reg_data;
            uint16_t crc16;
        }func_03_send;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint8_t  bytes;
            uint16_t  *input_reg_data;
            uint16_t crc16;
        }func_04_send;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t coil_addr;
            uint16_t coil_data;
            uint16_t crc16;
        }func_05_send;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t hold_reg_addr;
            uint16_t hold_reg_data;
            uint16_t crc16;
        }func_06_send;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t start_addr;
            uint16_t coil_num;
            uint16_t crc16;
        }func_15_send;
        struct {
            uint8_t  dev_addr;
            uint8_t  func_code;
            uint16_t start_addr;
            uint16_t reg_num;
            uint16_t crc16;
        }func_16_send;
    };
    uint8_t err_code;
    uint8_t data_out[512];
//    uint8_t recv_buff[1024];
    uint8_t send_buff[520];
}vdata_modbus_slave_t;

extern vdata_modbus_slave_t vdata_modbus_slave_data;
extern uint16_t vdata_modbus_hold_reg_1[MAX_HOLD_REG_NUM];
extern uint16_t vdata_modbus_hold_reg_1_w[MAX_HOLD_REG_NUM];
extern vdata_modbus_hold_reg_t vdata_modbus_hold_reg[];

uint16_t modbus_crc16(uint8_t *puchMsg, uint16_t usDataLen);
uint16_t vdata_modbus_slave_process(vdata_modbus_slave_t *pdata);
uint16_t vdata_modbus_slave_packet(vdata_modbus_slave_t *pdata);
uint16_t vdata_modbus_slave_parse(vdata_modbus_slave_t *pdata, uint8_t *raw_data, uint16_t length);

uint16_t vdata_modbus_get_hold_reg(uint16_t reg_addr);
uint16_t vdata_modbus_set_hold_reg(uint16_t reg_addr, uint16_t reg_value);

void vdata_modbus_data_out(uint8_t *buff, uint16_t length);
void vdata_set_modbus_slave_addr(uint8_t slave_addr);

